/**
 * 给定nums数组，两种操作
 * 1 s e: 求[s, e]区间中峰值的数量
 * 2 p v: 将nums[p]改为v
 * 
 * 注意到2操作最多只影响三个位置，因此使用树状数组记录峰值的数量
 * 对于i位置如果是峰值就令 modify(i, 1)
 * 对1操作，query(s+1,e-1) 即可
 * 对2操作，检查 i-1, i, i+1 三个位置，根据情况进行modify即可
 */
struct FenwickTree{ // 树状数组

using value_type = long long int;
using vec_type = vector<value_type>;

int n;
vec_type c;

FenwickTree() = default;

static int lowbit(int x){return x & -x;}

void init(int nn){this->c.assign((this->n=nn) + 1, 0);}

void modify(int pos, value_type delta){
    for(int i=pos;i<=this->n;i+=lowbit(i)) this->c[i] += delta;
}

value_type query(int pos)const{
    value_type ans = 0;
    for(int i=pos;i;i-=lowbit(i)) ans += this->c[i];
    return ans;
}

value_type query(int s, int e)const{return this->query(e) - this->query(s - 1);}

};

class Solution {

int N;
FenwickTree Bt;

public:
    vector<int> countOfPeaks(vector<int>& nums, vector<vector<int>>& queries) {
        nums.insert(nums.begin(), 0x3F4F5F6F);        
        int n = nums.size() - 1;
        N = n;
        Bt.init(n);
        for(int i=1;i<n;++i){
            if(nums[i - 1] < nums[i] and nums[i + 1] < nums[i]){
                Bt.modify(i, 1);
            }
        }
        
        vector<int> ans;
        for(const auto & q : queries){
            int cmd = q[0];
            int s = q[1] + 1;            
            if(1 == cmd){
                int e = q[2] + 1;
                auto tmp = 0;
                if(s + 1 <= e - 1){
                    tmp = Bt.query(s + 1, e - 1);
                }
                ans.emplace_back(tmp);
            }else if(2 == cmd){
                int v = q[2];                
                this->check(nums, s, v);
            }else{
                assert(0);
            }
        }
        return ans;
    }

    void check(vector<int>& a, int pos, int v){
        bool pre, cur;
        if(pos > 2){
            pre = a[pos - 2] < a[pos - 1] and a[pos] < a[pos - 1];
            cur = a[pos - 2] < a[pos - 1] and v < a[pos - 1];
            if(pre != cur){
                if(pre){
                    Bt.modify(pos - 1, -1);
                }else{
                    Bt.modify(pos - 1, 1);
                }
            }
        }
        if(pos + 1 < N){
            pre = a[pos + 2] < a[pos + 1] and a[pos] < a[pos + 1];
            cur = a[pos + 2] < a[pos + 1] and v < a[pos + 1];
            if(pre != cur){
                if(pre){
                    Bt.modify(pos + 1, -1);
                }else{
                    Bt.modify(pos + 1, 1);
                }
            }
        }

        if(1 < pos and pos < N){
            pre = a[pos - 1] < a[pos] and a[pos + 1] < a[pos];
            cur = a[pos - 1] < v and a[pos + 1] < v;
            if(pre != cur){
                if(pre){
                    Bt.modify(pos, -1);
                }else{
                    Bt.modify(pos, 1);
                }
            }
        }

        a[pos] = v;
        return;
    }
};